<!--
使用antd原生Form生成 详细用法参考ant-design-vue Form组件文档
vscode默认配置文件会自动格式化/移除未使用依赖
-->
<script setup lang="ts">
import type { RuleObject } from 'ant-design-vue/es/form';
import { computed, ref, reactive, watch } from 'vue';

import { Input, Textarea, Select, RadioGroup, CheckboxGroup, DatePicker, Form, FormItem, Button, Space,Row, Col, Modal, message } from 'ant-design-vue';
import { confirm, prompt } from '@vben/common-ui';
import { ImageUpload, FileUpload } from '#/components/upload';
import { Tinymce } from '#/components/tinymce';
import { getPopupContainer } from '@vben/utils';
import { pick } from 'lodash-es';

import { getDictOptions } from '#/utils/dict';

import { useVbenDrawer } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { cloneDeep } from '@vben/utils';

import { useVbenForm } from '#/adapter/form';
import { useVbenVxeGrid, type VxeGridProps } from '#/adapter/vxe-table';
import { generateContractNo } from '#/utils/generator';
import {
  saleContractAdd,
  saleContractInfo,
  saleContractUpdate,
  saleContractRemove,
  saleContractSubmit,
  saleContractApprove,
  saleContractInvalidate,
  saleContractList,
} from '#/api/trade/saleContract';
import { customerList, customerInfo } from '#/api/trade/customer';
import { userList } from '#/api/system/user';
import type { DefaultOptionType, SelectValue } from 'ant-design-vue/es/select';
import type { SaleContractForm, SaleContractDetailVO } from '#/api/trade/saleContract/model';
import { useBeforeCloseDiff } from '#/utils/popup';
import SaleContractDetails from './components/SaleContractDetails.vue';
import type { ID } from '#/api/common';
import { APPROVE_STATUS } from '../constants';


const emit = defineEmits<{ reload: [] }>();


const isUpdate = ref(false);
const title = computed(() => {
  return isUpdate.value ? $t('pages.common.edit') : $t('pages.common.add');
});

// 当前合同状态
const currentStatus = computed(() => formData.value.status || APPROVE_STATUS.DRAFT);

// 是否可编辑
const isEditable = computed(() => {
  return currentStatus.value === APPROVE_STATUS.DRAFT || 
         currentStatus.value === APPROVE_STATUS.REJECTED;
});

// 驳回原因是否可见
const showRejectReason = computed(() => {
  return formData.value.rejectReason && formData.value.rejectReason.trim() !== '';
});

/**
 * 定义默认值 用于reset
 */
const defaultValues: Partial<SaleContractForm> = {
  id: undefined,
  deptId: undefined,
  contractNo: undefined,
  contractDate: new Date().toISOString().slice(0, 19).replace('T', ' '),
  customerId: undefined,
  contact: undefined,
  contactPhone: undefined,
  saleUserid: undefined,
  currency: undefined,
  downpaymentPercent: undefined,
  totalAmount: undefined,
  paidAmount: undefined,
  unpayAmount: undefined,
  saleCount: undefined,
  attachments: undefined,
  status: 'draft',
  rejectReason: undefined,
  details: [],
}

/**
 * 表单数据ref
 */
const formData = ref(defaultValues);

// 附件列表，用于FileUpload组件的双向绑定
const attachmentsList = ref<string[]>([]);

// 处理附件变化
const handleAttachmentsChange = () => {
  // 将数组转换为逗号分割的字符串
  formData.value.attachments = attachmentsList.value.length > 0 
    ? attachmentsList.value.join(',') 
    : undefined;
};

// 监听formData.attachments变化，同步到attachmentsList
watch(
  () => formData.value.attachments,
  (newAttachments) => {
    if (newAttachments && typeof newAttachments === 'string') {
      // 将逗号分割的字符串转换为数组
      attachmentsList.value = newAttachments.split(',').filter(id => id.trim());
    } else {
      attachmentsList.value = [];
    }
  },
  { immediate: true }
);



// 客户列表数据
const customerOptions = ref<{label: string; value: string | number}[]>([]);
const customerLoading = ref(false);

// 销售人员列表数据
const saleUserOptions = ref<{label: string; value: string | number}[]>([]);
const saleUserLoading = ref(false);

// 加载客户列表
const loadCustomerOptions = async (keyword?: string) => {
  customerLoading.value = true;
  try {
    const {rows} = await customerList({
      pageNum: 1,
      pageSize: 200,
      name: keyword // 使用name字段作为搜索条件
    });
    customerOptions.value = rows.map(item => ({
      label: item.name,
      value: item.id
    }));
  } finally {
    customerLoading.value = false;
  }
};

// 初始加载客户列表
loadCustomerOptions();

// 加载销售人员列表
const loadSaleUserOptions = async () => {
  saleUserLoading.value = true;
  try {
    const { rows } = await userList({
      pageNum: 1,
      pageSize: 200
    });
    saleUserOptions.value = rows.map(item => ({
      label: item.nickName,
      value: item.userId
    }));
  } finally {
    saleUserLoading.value = false;
  }
};

// 初始加载销售人员列表
loadSaleUserOptions();

// 自动计算合同总价
const calculateTotalAmount = () => {
  if (!formData.value.details || formData.value.details.length === 0) {
    formData.value.totalAmount = 0;
    return;
  }
  
  const total = formData.value.details.reduce((sum, detail) => {
    return sum + (detail.amount || 0);
  }, 0);
  
  formData.value.totalAmount = Number(total.toFixed(3));
};

// 自动计算销售数量
const calculateSaleCount = () => {
  formData.value.saleCount = formData.value.details ? formData.value.details.length : 0;
};

// 自动计算已付金额
const calculatePaidAmount = () => {
  const total = formData.value.totalAmount || 0;
  const percent = formData.value.downpaymentPercent || 0;
  formData.value.paidAmount = Number((total * percent / 100).toFixed(3));
};

// 自动计算未付金额
const calculateUnpayAmount = () => {
  const total = formData.value.totalAmount || 0;
  const paid = formData.value.paidAmount || 0;
  formData.value.unpayAmount = Number((total - paid).toFixed(3));
};

// 监听销售明细变化，自动计算合同总价和销售数量
watch(
  () => formData.value.details,
  () => {
    calculateSaleCount();
    calculateTotalAmount();
    calculatePaidAmount();
    calculateUnpayAmount();
  },
  { deep: true }
);

// 监听首付比例变化，自动计算已付金额和未付金额
watch(
  () => formData.value.downpaymentPercent,
  () => {
    calculatePaidAmount();
    calculateUnpayAmount();
  }
);

// 监听合同总价变化，自动计算已付金额和未付金额
watch(
  () => formData.value.totalAmount,
  () => {
    calculatePaidAmount();
    calculateUnpayAmount();
  }
);

// 监听客户选择变化，自动填充联系人、联系方式和销售信息
const handleCustomerChange = async (value: SelectValue) => {
  if (!value) return;
  
  try {
    const customerData = await customerInfo(value as ID);
    if (customerData) {
      // 自动填充联系人、联系方式和销售信息
      formData.value.contact = customerData.contact;
      formData.value.contactPhone = customerData.contactPhone;
      formData.value.saleUserid = customerData.saleUserid;
    }
  } catch (error) {
    console.error('获取客户详情失败', error);
  }
};

type AntdFormRules<T> = Partial<Record<keyof T, RuleObject[]>> & {
  [key: string]: RuleObject[];
};
/**
 * 表单校验规则
 */
const formRules = ref<AntdFormRules<SaleContractForm>>({
    // contractNo 改为非必填，提交时自动生成
    // contractNo: [
    //   { required: true, message: "合同号不能为空" }
    // ],
    contractDate: [
      { required: true, message: "合同日期不能为空" }
    ],
    customerId: [
      { required: true, message: "客户名称不能为空" }
    ],
    contact: [
      { required: true, message: "联系人不能为空" }
    ],
    contactPhone: [
      { required: true, message: "联系方式不能为空" }
    ],
    saleUserid: [
      { required: true, message: "销售不能为空" }
    ],
    currency: [
      { required: true, message: "币种不能为空" }
    ],
    downpaymentPercent: [
      { required: true, message: "首付比例不能为空" },
      { 
        validator: (rule: any, value: number) => {
          if (value && (value < 1 || value > 100)) {
            return Promise.reject('首付比例必须在1%~100%之间');
          }
          return Promise.resolve();
        }
      }
    ],
    // totalAmount, paidAmount, unpayAmount, saleCount 为自动计算字段，无需验证
    // status: [
    //   { required: true, message: "合同状态不能为空" }
    // ],
    details: [
      { 
        required: true, 
        validator: (rule: any, value: SaleContractDetailVO[]) => {
          if (!value || value.length === 0) {
            return Promise.reject('至少需要添加一个销售明细');
          }
          for (let i = 0; i < value.length; i++) {
            const item = value[i]!;
            if (!item.brandId) {
              return Promise.reject(`商品${i + 1}请选择品牌`);
            }
            if (!item.spuId) {
              return Promise.reject(`商品${i + 1}请选择SPU`);
            }
            if (!item.skuId) {
              return Promise.reject(`商品${i + 1}请选择SKU`);
            }
            if (!item.amount || item.amount <= 0) {
              return Promise.reject(`商品${i + 1}请输入有效售价`);
            }
          }
          return Promise.resolve();
        }
      }
    ],
});

 
/**
 * useForm解构出表单方法
 */
const { validate, validateInfos, resetFields } = Form.useForm(
  formData,
  formRules,
);

function customFormValueGetter() {
  return JSON.stringify(formData.value);
}

const { onBeforeClose, markInitialized, resetInitialized } = useBeforeCloseDiff(
  {
    initializedGetter: customFormValueGetter,
    currentGetter: customFormValueGetter,
  },
);

// 作废合同
const handleInvalidate = async () => {
  try {
    await confirm({
      title: '确认作废',
      content: '确定要作废该合同吗？作废后无法恢复。',
    });
    
    await saleContractInvalidate({id:formData.value.id!});
    message.success('作废成功');
    emit('reload');
    drawerApi.close();
  } catch (error) {
    if (error !== 'cancel') {
      console.error('作废失败:', error);
    }
  }
};

// 审核通过
const handleApprove = async () => {
  try {
    await confirm({
      title: '确认通过',
      content: '确定要通过该合同吗？',
    });
    
    await saleContractApprove(formData.value.id!,true);
    message.success('审核通过成功');
    emit('reload');
    drawerApi.close();
  } catch (error) {
    if (error !== 'cancel') {
      console.error('审核通过失败:', error);
    }
  }
};

// 驳回合同
const handleReject = async () => {
  try {
    const reason = await prompt<string>({
      title: '驳回合同',
      content: '请输入驳回原因：',
      componentProps: {
        placeholder: '请输入驳回原因（不超过200字）',
      },
      beforeClose({ isConfirm, value }) {
        if (!isConfirm) return true;
        if (!value || !value.trim()) {
          message.error('请输入驳回原因');
          return false;
        }
        if (value.trim().length > 200) {
          message.error('驳回原因不能超过200字');
          return false;
        }
        return true;
      },
    });
    
    if (reason && reason.trim()) {
      await saleContractApprove(formData.value.id!, false, reason.trim());
      message.success('驳回成功');
      emit('reload');
      drawerApi.close();
    }
  } catch (error) {
    // 用户取消操作或其他错误
    if (error !== 'cancel') {
      console.error('驳回失败:', error);
    }
  }
};

// 重新提交
const handleSubmit = async () => {
  try {
    drawerApi.lock(true);
    await validate();
    
    // 如果合同号为空，自动生成
    if (!formData.value.contractNo || formData.value.contractNo.trim() === '') {
      formData.value.contractNo = generateContractNo();
    }
    const data = cloneDeep(formData.value);
    // 先更新 或 新建合同信息
    await (isUpdate.value ? saleContractUpdate(data) : saleContractAdd(data));
    if(!isUpdate.value){
        //获取当前合同的id
      const currentContract = await saleContractList({
          contractNo: data.contractNo,
      });
      if (currentContract.total > 0) {
       formData.value.id = currentContract.rows[0]?.id;
      }
    }
    // 再提交审核
    await saleContractSubmit([formData.value.id!]);
    resetInitialized();
    emit('reload');
    drawerApi.close();
  } catch (error) {
    console.error('重新提交失败:', error);
  } finally {
    drawerApi.lock(false);
  }
};

const [BasicDrawer, drawerApi] = useVbenDrawer({
  class: 'w-[900px]',
  onBeforeClose,
  onClosed: handleClosed,
  onConfirm: handleConfirm,
  showConfirmButton: false, // 隐藏默认确认按钮，使用自定义按钮
  showCancelButton: false,  // 隐藏默认取消按钮
  onOpenChange: async (isOpen) => {
    if (!isOpen) {
      return null;
    }
    drawerApi.drawerLoading(true);

    const { id } = drawerApi.getData() as { id?: number | string };
    isUpdate.value = !!id;

    if (isUpdate.value && id) {
      const record = await saleContractInfo(id);
      // 只赋值存在的字段
      const filterRecord = pick(record, Object.keys(defaultValues));
      formData.value = filterRecord;
      
      
      // 编辑模式下，需要额外获取客户信息来填充联系人和联系方式
      if (record.customerId) {
        try {
          const customerData = await customerInfo(record.customerId);
          if (customerData) {
            formData.value.contact = customerData.contact;
            formData.value.contactPhone = customerData.contactPhone;
          }
        } catch (error) {
          console.error('获取客户详情失败', error);
        }
      }
      
      // 销售明细数据已经在filterRecord中
    } else {
      // 新增时清空销售明细
      formData.value.details = [];
    }
    await markInitialized();

    drawerApi.drawerLoading(false);
  },
}); 

// 生成合同号的函数已提取到 #/utils/generator.ts

async function handleConfirm() {
  try {
    drawerApi.lock(true);
    await validate();
    // 可能会做数据处理 使用cloneDeep深拷贝
    const data = cloneDeep(formData.value);
    
    // 如果合同号为空，自动生成
    if (!data.contractNo || data.contractNo.trim() === '') {
      data.contractNo = generateContractNo();
    }
    
    await (isUpdate.value ? saleContractUpdate(data) : saleContractAdd(data));
    resetInitialized();
    emit('reload');
    drawerApi.close();
  } catch (error) {
    console.error(error);
  } finally {
    drawerApi.lock(false);
  }
}

async function handleClosed() {
  formData.value = cloneDeep(defaultValues);
  resetFields();
  resetInitialized();
}
</script>

<template>
  <BasicDrawer :title="title" :width="1000">
    <Form :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
      <Row :gutter="16">
        <Col :span="12">
          <FormItem label="合同号" v-bind="validateInfos.contractNo">
            <Input v-model:value="formData.contractNo" placeholder="请输入合同号，忽略则自动生成" :disabled="!isEditable" />
          </FormItem>
        </Col>
        <Col :span="12">
          <FormItem label="合同日期" v-bind="validateInfos.contractDate">
            <DatePicker 
              v-model:value="formData.contractDate"
              format="YYYY-MM-DD"
              value-format="YYYY-MM-DD HH:mm:ss"
              style="width: 100%"
              :disabled="!isEditable"
            />
          </FormItem>
        </Col>
      </Row>
      
      <Row :gutter="16">
        <Col :span="12">
          <FormItem label="客户名称" v-bind="validateInfos.customerId">
            <Select
              v-model:value="formData.customerId"
              :options="customerOptions"
              :loading="customerLoading"
              show-search
              :filter-option="false"
              :getPopupContainer="getPopupContainer"
              :placeholder="$t('ui.formRules.selectRequired')"
              @search="loadCustomerOptions"
              @change="handleCustomerChange"
              :disabled="!isEditable"
            />
          </FormItem>
        </Col>
        <Col :span="12">
          <FormItem label="联系人" v-bind="validateInfos.contact">
            <Input v-model:value="formData.contact" :placeholder="$t('ui.formRules.required')" disabled />
          </FormItem>
        </Col>
      </Row>
      
      <Row :gutter="16">
        <Col :span="12">
          <FormItem label="联系方式" v-bind="validateInfos.contactPhone">
            <Input v-model:value="formData.contactPhone" :placeholder="$t('ui.formRules.required')" disabled />
          </FormItem>
        </Col>
        <Col :span="12">
          <FormItem label="销售" v-bind="validateInfos.saleUserid">
            <Select
              v-model:value="formData.saleUserid"
              :options="saleUserOptions"
              :loading="saleUserLoading"
              show-search
              :filter-option="(input, option) => (option?.label ?? '').toString().toLowerCase().includes(input.toLowerCase())"
              :getPopupContainer="getPopupContainer"
              :placeholder="$t('ui.formRules.selectRequired')"
              :disabled="!isEditable"
            />
          </FormItem>
        </Col>
      </Row>
      <Row>
        <!-- 销售明细部分 -->
        <Col :span="24">
          <FormItem v-bind="validateInfos.details" :wrapper-col="{ span: 24 }" :label-col="{ span: 0 }">
            <SaleContractDetails v-model="formData.details!" :disabled="!isEditable" />
          </FormItem>
        </Col>
      </Row>
      

      <Row :gutter="16">
        <Col :span="12">
          <FormItem label="币种" v-bind="validateInfos.currency">
            <Select
              v-model:value="formData.currency"
              :options="getDictOptions('currency')"
              :getPopupContainer="getPopupContainer"
              :placeholder="$t('ui.formRules.selectRequired')"
              :disabled="!isEditable"
            />
          </FormItem>
        </Col>
        <Col :span="12">
          <FormItem label="首付比例" v-bind="validateInfos.downpaymentPercent">
            <Input v-model:value="formData.downpaymentPercent" :placeholder="$t('ui.formRules.required')" :disabled="!isEditable" />
          </FormItem>
        </Col>
      </Row>
      
      <Row :gutter="16">
        <Col :span="12">
          <FormItem label="合同总价" v-bind="validateInfos.totalAmount">
            <Input v-model:value="formData.totalAmount" placeholder="自动计算" disabled />
          </FormItem>
        </Col>
        <Col :span="12">
          <FormItem label="已付金额" v-bind="validateInfos.paidAmount">
            <Input v-model:value="formData.paidAmount" placeholder="自动计算" disabled />
          </FormItem>
        </Col>
      </Row>
      
      <Row :gutter="16">
        <Col :span="12">
          <FormItem label="未付金额" v-bind="validateInfos.unpayAmount">
            <Input v-model:value="formData.unpayAmount" placeholder="自动计算" disabled />
          </FormItem>
        </Col>
        <Col :span="12">
          <FormItem label="销售数量" v-bind="validateInfos.saleCount">
            <Input v-model:value="formData.saleCount" placeholder="自动计算" disabled />
          </FormItem>
        </Col>
      </Row>
      
      <!-- 合同附件单独一行，因为可能需要更多空间 -->
      <Row>
        <Col :span="24">
          <FormItem label="合同附件" v-bind="validateInfos.attachments" :label-col="{ span: 3 }" :wrapper-col="{ span: 21 }">
            <FileUpload 
              :max-count="10" 
              v-model:value="attachmentsList" 
              @change="handleAttachmentsChange"
              accept=".jpg,.jpeg,.png,.gif,.webp,.xlsx,.csv,.docx,.pdf"
              :disabled="!isEditable"
            />
          </FormItem>
        </Col>
      </Row>
            <!-- 驳回原因字段，仅在有驳回原因时显示 -->
            <Row v-if="showRejectReason">
        <Col :span="24">
          <FormItem label="驳回原因" :label-col="{ span: 3 }" :wrapper-col="{ span: 21 }">
            <Textarea 
              v-model:value="formData.rejectReason" 
              :rows="3" 
              placeholder="驳回原因" 
              disabled
              :maxlength="200"
              show-count
            />
          </FormItem>
        </Col>
      </Row>
    </Form>
    
    <!-- 自定义按钮区域 -->
    <template #footer>
      <div class="flex justify-between">
        <!-- 操作按钮 -->
        <div class="flex space-x-3">
          <Button v-if="formData.status === APPROVE_STATUS.DRAFT || formData.status === APPROVE_STATUS.REJECTED" type="primary" @click="handleSubmit">提交审核</Button>
          <Button v-if="formData.status === APPROVE_STATUS.WAITING" type="primary" @click="handleApprove">通过</Button>
          <Button v-if="formData.status === APPROVE_STATUS.WAITING" danger @click="handleReject">驳回</Button>
          <Button v-if="formData.status === APPROVE_STATUS.DRAFT ||  formData.status === APPROVE_STATUS.REJECTED" danger @click="handleInvalidate">作废</Button>
          <Button  v-if="!formData.status || formData.status === APPROVE_STATUS.DRAFT || formData.status === APPROVE_STATUS.REJECTED" type="primary" @click="handleConfirm">仅保存</Button>
          <Button @click="drawerApi.close()">返回</Button>
        </div>
      </div>

    </template>
  </BasicDrawer>
</template>

